import os
import sys
import tkinter as tk
from tkinter import filedialog, messagebox, ttk
import glob

class FileModifierApp:
    def __init__(self, root):
        self.root = root
        self.root.title("文件批量修改工具 V1")
        self.root.geometry("600x700")
        self.root.resizable(True, True)
        
        self.head_content = ""
        self.end_content = ""
        self.target_directory = ""
        self.confirm_each_file = tk.BooleanVar(value=True)
        self.skip_processed_files = tk.BooleanVar(value=True)
        
        self.create_widgets()
        
        # 自动加载当前目录下的head.txt和end.txt文件
        self.auto_load_files()
        
    def create_widgets(self):
        # 创建主框架
        main_frame = ttk.Frame(self.root, padding="10")
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 头部文件选择
        head_frame = ttk.LabelFrame(main_frame, text="头部文件", padding="5")
        head_frame.pack(fill=tk.X, pady=5)
        
        self.head_path_var = tk.StringVar()
        ttk.Entry(head_frame, textvariable=self.head_path_var, width=50).pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True)
        ttk.Button(head_frame, text="浏览", command=self.load_head_file).pack(side=tk.RIGHT, padx=5)
        
        # 尾部文件选择
        end_frame = ttk.LabelFrame(main_frame, text="尾部文件", padding="5")
        end_frame.pack(fill=tk.X, pady=5)
        
        self.end_path_var = tk.StringVar()
        ttk.Entry(end_frame, textvariable=self.end_path_var, width=50).pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True)
        ttk.Button(end_frame, text="浏览", command=self.load_end_file).pack(side=tk.RIGHT, padx=5)
        
        # 目标目录选择
        dir_frame = ttk.LabelFrame(main_frame, text="目标目录", padding="5")
        dir_frame.pack(fill=tk.X, pady=5)
        
        self.dir_path_var = tk.StringVar()
        ttk.Entry(dir_frame, textvariable=self.dir_path_var, width=50).pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True)
        ttk.Button(dir_frame, text="浏览", command=self.select_directory).pack(side=tk.RIGHT, padx=5)
        
        # 文件预览区域
        preview_frame = ttk.LabelFrame(main_frame, text="文件预览", padding="5")
        preview_frame.pack(fill=tk.BOTH, expand=True, pady=5)
        
        # 创建一个带滚动条的文本框
        self.preview_text = tk.Text(preview_frame, wrap=tk.WORD, height=10)
        self.preview_text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        
        scrollbar = ttk.Scrollbar(preview_frame, command=self.preview_text.yview)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.preview_text.config(yscrollcommand=scrollbar.set)
        
        # 进度条
        self.progress_var = tk.DoubleVar()
        self.progress_bar = ttk.Progressbar(main_frame, variable=self.progress_var, maximum=100)
        self.progress_bar.pack(fill=tk.X, pady=5)
        
        # 状态标签
        self.status_var = tk.StringVar(value="准备就绪")
        status_label = ttk.Label(main_frame, textvariable=self.status_var)
        status_label.pack(anchor=tk.W, pady=2)
        
        # 选项区域
        options_frame = ttk.LabelFrame(main_frame, text="选项", padding="5")
        options_frame.pack(fill=tk.X, pady=5)
        
        ttk.Checkbutton(options_frame, text="处理每个文件时手动确认", variable=self.confirm_each_file).pack(anchor=tk.W, padx=5)
        
        # 添加跳过已处理文件的选项
        self.skip_processed_files = tk.BooleanVar(value=True)
        ttk.Checkbutton(options_frame, text="跳过已处理文件（防止重复修改）", variable=self.skip_processed_files).pack(anchor=tk.W, padx=5)
        
        # 按钮区域
        button_frame = ttk.Frame(main_frame)
        button_frame.pack(fill=tk.X, pady=10)
        
        # 创建一个更大的执行按钮
        execute_button = ttk.Button(button_frame, text="执行", command=self.process_files)
        execute_button.pack(side=tk.RIGHT, padx=10, pady=5, ipadx=20, ipady=5)
    
    def load_head_file(self):
        file_path = filedialog.askopenfilename(title="选择头部文件", filetypes=[("文本文件", "*.txt"), ("所有文件", "*.*")])
        if file_path:
            self.head_path_var.set(file_path)
            try:
                # 尝试多种编码方式读取文件
                self.load_file_with_encoding(file_path, is_head=True)
                self.update_preview()
                self.status_var.set(f"已加载头部文件: {os.path.basename(file_path)}")
            except Exception as e:
                messagebox.showerror("错误", f"无法读取头部文件: {str(e)}")
    
    def load_end_file(self):
        file_path = filedialog.askopenfilename(title="选择尾部文件", filetypes=[("文本文件", "*.txt"), ("所有文件", "*.*")])
        if file_path:
            self.end_path_var.set(file_path)
            try:
                # 尝试多种编码方式读取文件
                self.load_file_with_encoding(file_path, is_head=False)
                self.update_preview()
                self.status_var.set(f"已加载尾部文件: {os.path.basename(file_path)}")
            except Exception as e:
                messagebox.showerror("错误", f"无法读取尾部文件: {str(e)}")
    
    def select_directory(self):
        directory = filedialog.askdirectory(title="选择目标目录")
        if directory:
            self.dir_path_var.set(directory)
            self.target_directory = directory
            self.status_var.set(f"已选择目标目录: {directory}")
            self.scan_directory()
    
    def scan_directory(self):
        if not self.target_directory:
            return
        
        self.preview_text.delete(1.0, tk.END)
        self.preview_text.insert(tk.END, "扫描目录中的文件...\n")
        
        c_files = []
        h_files = []
        
        for root, _, files in os.walk(self.target_directory):
            for file in files:
                if file.endswith(".c") or file.endswith(".h"):
                    full_path = os.path.join(root, file)
                    rel_path = os.path.relpath(full_path, self.target_directory)
                    if file.endswith(".c"):
                        c_files.append(rel_path)
                    else:
                        h_files.append(rel_path)
        
        self.preview_text.delete(1.0, tk.END)
        self.preview_text.insert(tk.END, f"找到 {len(c_files)} 个 .c 文件和 {len(h_files)} 个 .h 文件\n\n")
        
        self.preview_text.insert(tk.END, "C 文件:\n")
        for file in c_files[:10]:  # 只显示前10个文件
            self.preview_text.insert(tk.END, f"  {file}\n")
        if len(c_files) > 10:
            self.preview_text.insert(tk.END, f"  ... 还有 {len(c_files) - 10} 个文件\n")
        
        self.preview_text.insert(tk.END, "\nH 文件:\n")
        for file in h_files[:10]:  # 只显示前10个文件
            self.preview_text.insert(tk.END, f"  {file}\n")
        if len(h_files) > 10:
            self.preview_text.insert(tk.END, f"  ... 还有 {len(h_files) - 10} 个文件\n")
    
    def update_preview(self):
        self.preview_text.delete(1.0, tk.END)
        
        if self.head_content:
            self.preview_text.insert(tk.END, "头部内容预览:\n")
            preview_head = self.head_content[:200] + ("..." if len(self.head_content) > 200 else "")
            self.preview_text.insert(tk.END, preview_head + "\n\n")
        
        if self.end_content:
            self.preview_text.insert(tk.END, "尾部内容预览:\n")
            preview_end = self.end_content[:200] + ("..." if len(self.end_content) > 200 else "")
            self.preview_text.insert(tk.END, preview_end)
    
    def process_files(self):
        if not self.head_content and not self.end_content:
            messagebox.showwarning("警告", "请至少加载一个头部或尾部文件")
            return
        
        if not self.target_directory:
            messagebox.showwarning("警告", "请选择目标目录")
            return
        
        # 获取所有.c和.h文件
        target_files = []
        for root, _, files in os.walk(self.target_directory):
            for file in files:
                if file.endswith(".c") or file.endswith(".h"):
                    target_files.append(os.path.join(root, file))
        
        if not target_files:
            messagebox.showinfo("信息", "目标目录中没有找到.c或.h文件")
            return
        
        # 确认操作
        if not messagebox.askyesno("确认", f"将修改 {len(target_files)} 个文件，是否继续？"):
            return
        
        # 处理文件
        self.progress_var.set(0)
        self.preview_text.delete(1.0, tk.END)
        self.preview_text.insert(tk.END, "正在处理文件...\n")
        
        modified_count = 0
        error_count = 0
        
        for i, file_path in enumerate(target_files):
            try:
                # 更新进度
                progress = (i + 1) / len(target_files) * 100
                self.progress_var.set(progress)
                self.status_var.set(f"正在处理: {os.path.basename(file_path)}")
                self.root.update_idletasks()
                
                # 读取文件内容，尝试多种编码
                content = ""
                encodings = ['utf-8', 'gbk', 'gb2312', 'latin-1']
                for encoding in encodings:
                    try:
                        with open(file_path, 'r', encoding=encoding) as file:
                            content = file.read()
                        break
                    except UnicodeDecodeError:
                        continue
                
                # 准备头部内容（替换%file%为文件名）
                file_name = os.path.basename(file_path)
                head_content = self.head_content.replace("%file%", file_name) if self.head_content else ""
                
                # 检查文件是否已经包含头部和尾部内容
                already_processed = False
                if self.skip_processed_files.get():
                    # 检查头部
                    if head_content and head_content.strip() and content.startswith(head_content.strip()):
                        self.preview_text.insert(tk.END, f"跳过(已有头部): {file_path}\n")
                        already_processed = True
                    
                    # 检查尾部
                    if not already_processed and self.end_content and self.end_content.strip() and content.endswith(self.end_content.strip()):
                        self.preview_text.insert(tk.END, f"跳过(已有尾部): {file_path}\n")
                        already_processed = True
                
                # 如果文件已处理且选择跳过，则继续下一个文件
                if already_processed:
                    continue
                
                # 如果需要手动确认每个文件
                if self.confirm_each_file.get():
                    if not messagebox.askyesno("确认", f"是否修改文件: {file_path}?"):
                        continue
                
                # 修改文件内容
                new_content = head_content + content + self.end_content
                
                # 写入文件
                with open(file_path, 'w', encoding='utf-8') as file:
                    file.write(new_content)
                
                modified_count += 1
                self.preview_text.insert(tk.END, f"已修改: {file_path}\n")
                
            except Exception as e:
                error_count += 1
                self.preview_text.insert(tk.END, f"错误: {file_path} - {str(e)}\n")
        
        # 完成处理
        self.progress_var.set(100)
        self.status_var.set(f"完成! 已修改 {modified_count} 个文件, {error_count} 个错误")
        
        skipped_count = len(target_files) - modified_count - error_count
        messagebox.showinfo("完成", f"已成功修改 {modified_count} 个文件\n跳过 {skipped_count} 个文件\n{error_count} 个文件处理失败")

    def load_file_with_encoding(self, file_path, is_head=True):
        """尝试多种编码方式读取文件"""
        encodings = ['utf-8', 'gbk', 'gb2312', 'latin-1']
        content = ""
        
        for encoding in encodings:
            try:
                with open(file_path, 'r', encoding=encoding) as file:
                    content = file.read()
                if is_head:
                    self.head_content = content
                else:
                    self.end_content = content
                return True
            except UnicodeDecodeError:
                continue
        
        raise Exception("无法以任何编码方式读取文件")
    
    def auto_load_files(self):
        """自动加载当前目录下的head.txt和end.txt文件"""
        # 获取程序运行目录，兼容exe打包后的情况
        if getattr(sys, 'frozen', False):
            # 如果是打包后的exe
            current_dir = os.path.dirname(sys.executable)
        else:
            # 如果是直接运行Python脚本
            current_dir = os.path.dirname(os.path.abspath(__file__))
        
        # 查找head.txt
        head_files = glob.glob(os.path.join(current_dir, "head.txt"))
        if head_files:
            try:
                self.head_path_var.set(head_files[0])
                self.load_file_with_encoding(head_files[0], is_head=True)
                self.status_var.set(f"已自动加载头部文件: {os.path.basename(head_files[0])}")
            except Exception as e:
                messagebox.showwarning("警告", f"自动加载头部文件失败: {str(e)}")
        
        # 查找end.txt
        end_files = glob.glob(os.path.join(current_dir, "end.txt"))
        if end_files:
            try:
                self.end_path_var.set(end_files[0])
                self.load_file_with_encoding(end_files[0], is_head=False)
                self.status_var.set(f"已自动加载尾部文件: {os.path.basename(end_files[0])}")
            except Exception as e:
                messagebox.showwarning("警告", f"自动加载尾部文件失败: {str(e)}")
        
        # 更新预览
        if self.head_content or self.end_content:
            self.update_preview()

if __name__ == "__main__":
    root = tk.Tk()
    app = FileModifierApp(root)
    root.mainloop()